#ifndef __AUDIOPLAYER_HPP__
#define __AUDIOPLAYER_HPP__

#include <stdint.h>
#include <sys/types.h>
#include <alsa/asoundlib.h>
#include <functional>
#include "Mp3Decoder.hpp"

class AudioPlayer;

typedef std::function<void(AudioPlayer *player)> AudioPlayerStateChageCB;
typedef std::function<void(AudioPlayer *player, int16_t *pcm, int32_t sampleCnt)> AudioPlayerPCMCB;


class AudioPlayer
{
public:
    enum State {
        IDLE,
        LOADING,
        PLAYING,
        PAUSED,
    };
    enum Error {
        DECODER_ERR,
    };
private:
    char *filePath;
    Mp3Decoder *decoder = nullptr;
    FRunLoop *runLoop;
    State state = State::IDLE;

    snd_pcm_t *alsaPCM = nullptr;
private:
    int ufdsCount = 0;
    struct pollfd *ufds = nullptr;
    FPoll **ufdsPoll = nullptr;
    bool alsaStart(const AudioPCMInfo *info);
    void alsaPoll(bool enable);
    void alsaStop();
    void alsaPause(bool enable);
    void tryWritePCM();
    int16_t pcm[2048];
    int pcmLen = 0;
    int pcmOffset = 0;

    long long prevWriteTick = 0;
    bool postedDestroy = false;
    void registDecoder(Mp3Decoder *decoder);
    ~AudioPlayer();
public:
    AudioPlayerStateChageCB stateChangeCB = NULL;
    AudioPlayerPCMCB pcmCB = NULL;
public:
    AudioPlayer(FRunLoop *runLoop, const char *path);
    const AudioPCMInfo *getPCMInfo();
    State getState();
    static const char *stateToString(State state);
    Error getErrorInfo(char **desc);
    void seekTo(int ms);
    bool load();
    bool resume();
    void pause();
    void stop();
    void destroy();
};

#endif
